package com.dianziq.im.server.cmd;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.DefaultFileRegion;
import org.jboss.netty.channel.FileRegion;
import org.jboss.netty.handler.codec.http.Cookie;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
import org.jboss.netty.handler.codec.http.HttpHeaders.Values;

import com.dianziq.im.server.ConnectionService;

public class Context {

	final Channel ch;
	final ConnectionService service;
	final String path;
	final Map<String, List<String>> params;
	final Set<Cookie> cookies;
	static Charset UTF8 = Charset.forName("UTF-8");
	public Context(Channel ch, ConnectionService service, String path,
			Map<String, List<String>> params, Set<Cookie> cookies) {
		this.ch = ch;
		this.service = service;
		this.params = params;
		this.path = path;
		this.cookies = cookies;
	}

	public Cookie getCookie(String name) {
		if (this.cookies == null) {
			return null;
		}
		for (Cookie c : cookies) {
			if (c.getName().equals(name)) {
				return c;
			}
		}
		return null;
	}

	public void sendError(String msg) {
		DefaultHttpResponse resp = new DefaultHttpResponse(
				HttpVersion.HTTP_1_1, HttpResponseStatus.SERVICE_UNAVAILABLE);
		resp.setHeader(Names.CONTENT_TYPE, "text/txt; charset=UTF-8");

		ChannelBuffer cb = ChannelBuffers.wrappedBuffer(msg.getBytes(UTF8));
		resp.setContent(cb);
		resp.setHeader(Names.CONNECTION, Values.KEEP_ALIVE);
		resp.setHeader(Names.CONTENT_LENGTH, cb.readableBytes());
		ch.write(resp);// .addListener(ChannelFutureListener.CLOSE);

	}

	public void sendOK(String msg) {
		DefaultHttpResponse resp = new DefaultHttpResponse(
				HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
		resp.setHeader(Names.CONTENT_TYPE, "text/txt; charset=UTF-8");

		ChannelBuffer cb = ChannelBuffers.wrappedBuffer(msg.getBytes(UTF8));
		resp.setContent(cb);
		resp.setHeader(Names.CONNECTION, Values.KEEP_ALIVE);
		resp.setHeader(Names.CONTENT_LENGTH, cb.readableBytes());
		ch.write(resp);// .addListener(ChannelFutureListener.CLOSE);

	}

	private static int parseInt(String s) {
		try {
			return Integer.parseInt(s);

		} catch (Exception e) {

		}
		return 0;

	}

	public String getParam(String key) {
		List<String> ss = this.params.get(key);
		if (ss == null || ss.size() == 0) {
			return null;
		}
		return ss.get(0);
	}

	public int getIntParam(String key) {
		String s = this.getParam(key);
		if (s == null) {
			return 0;
		}
		try {
			return Integer.parseInt(s);
		} catch (Exception e) {
			return 0;
		}
	}

	public int getUserId() {
		int userId = 0;
		// int lastMsgId = 0;
		Cookie c = this.getCookie("UID");
		if (c != null) {
			String uid = c.getValue();
			if (uid != null) {
				int i = uid.indexOf('_');
				if (i > 0) {
					userId = parseInt(uid.substring(0, i));

				}
			}
		}

		if (userId == 0) {

			List<String> suids = params.get("uid");
			if (suids != null) {
				userId = parseInt(suids.get(0));
			}
		}
		return userId;
	}

	public void serveStatic(File file) throws IOException {
		RandomAccessFile raf;
		try {
			raf = new RandomAccessFile(file, "r");
		} catch (FileNotFoundException fnfe) {

			return;
		}
		DefaultHttpResponse resp = new DefaultHttpResponse(
				HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
		resp.setHeader(Names.CONTENT_TYPE,
				file.getName().endsWith(".js") ? "application/javascript"
						: "text/html");
		long fileLength = raf.length();
		resp.setHeader(Names.CONTENT_LENGTH, fileLength);

		ch.write(resp);// .addListener(ChannelFutureListener.CLOSE);
		final FileRegion region = new DefaultFileRegion(raf.getChannel(), 0,
				fileLength);
		ch.write(region).addListener(new ChannelFutureListener() {

			@Override
			public void operationComplete(ChannelFuture future)
					throws Exception {
				region.releaseExternalResources();
				future.getChannel().close();

			}

		});

	}
}
